/* Copyright (C) 
 * 
 * Disclaim
 * This program is the property of AI Speech Ltd. It shall be communicated to
 * authorized personnel only. It is not to be disclosed outside the group without
 * prior written consent. If you are not sure if you’re authorized to read this
 * program, please contact info@aispeech.com before reading.
 * 
 */


#ifndef ___WXM71__AISDS_WTK_INT_HASH__HEADER___
#define ___WXM71__AISDS_WTK_INT_HASH__HEADER___

#ifdef __cplusplus 
extern "C" {
#endif 

#include "wtk/core/cfg/wtk_main_cfg.h"

typedef struct wtk_sds_int_dict wtk_sds_int_dict_t;


/**
 * @brief key-value pair dict, in specially, key is wtk_string_t, and value is an integer
 */
struct wtk_sds_int_dict {
    wtk_heap_t *heap;
    wtk_str_hash_t *val;
};

wtk_sds_int_dict_t* wtk_sds_int_dict_new(wtk_heap_t *heap);
void wtk_sds_int_dict_reset(wtk_sds_int_dict_t *dict);
void wtk_sds_int_dict_delete(wtk_sds_int_dict_t *dict);


/**
 * @brief increase value of a given key
 *
 * @param dict dict where to find value
 * @param key  key used to find value
 * @param len length of key string
 * @param n number to increate
 *
 * @note if can't find given key, this function will create a new item 
 * named wtih key, and set it's value to n.
 */
void wtk_sds_int_dict_inc(wtk_sds_int_dict_t *dict, char *key, int len, int n);
#define wtk_sds_int_dict_inc_s(dict, s, n) wtk_sds_int_dict_inc(dict, s, strlen(s), n)
#define wtk_sds_int_dict_inc_str(dict, str, n) wtk_sds_int_dict_inc(dict, str->data, str->len, n)


/**
 * @brief same as wtk_sds_int_dict_inc, but is decrease 
 *
 * @note this function will also create a missing item and set value to 0
 */
void wtk_sds_int_dict_dec(wtk_sds_int_dict_t *dict, char *key, int len, int n);
#define wtk_sds_int_dict_dec_s(dict, s, n) wtk_sds_int_dict_dec(dict, s, strlen(s), n)
#define wtk_sds_int_dict_dec_str(dict, str, n) wtk_sds_int_dict_dec(dict, str->data, str->len, n)


/**
 * @brief get an value with given key from dict 
 *
 * @return 0 on success, -1 on failure
 *
 * @note the last parameter is used as output buffer, as if we return a integer 
 * as result, it's hard to note caller that there is no item have key as given
 */
int wtk_sds_int_dict_get(wtk_sds_int_dict_t *dict, char *key, int len, int *recv);
#define wtk_sds_int_dict_get_s(dict, s, recv) wtk_sds_int_dict_get(dict, s, strlen(s), recv)
#define wtk_sds_int_dict_get_str(dict, str, recv) wtk_sds_int_dict_get(dict, str->data, str->len, recv)

void wtk_sds_int_dict_set(wtk_sds_int_dict_t *dict, char *key, int len, int val);
#define wtk_sds_int_dict_set_s(dict, s, recv) wtk_sds_int_dict_set(dict, s, strlen(s), recv)
#define wtk_sds_int_dict_set_str(dict, str, recv) wtk_sds_int_dict_set(dict, str->data, str->len, recv)


/**
 * @brief sort the dict by val
 */
wtk_array_t* wtk_sds_int_dict_sort(wtk_sds_int_dict_t *dict);


int wtk_sds_int_dict_get_val_num(wtk_sds_int_dict_t *dict);

hash_str_node_t* wtk_sds_int_dict_begin(wtk_sds_int_dict_t *dict);
hash_str_node_t* wtk_sds_int_dict_next(wtk_sds_int_dict_t *dict);

#ifdef __cplusplus  
};
#endif

#endif
